/**
 * TODO: Vložit licenci.
 */

package cz.enif.commander.sources;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import cz.enif.commander.Logger;

/**
 * Čtenář zdroje typu soubor.
 * 
 * @author enif
 *
 */
final class FileSource implements ISource
{
	//// CONSTANTS ////
	
	/** Kódování, v kterém je očekáván vstup. */
	public static final String EXPECTED_FILE_ENCODING = "UTF-8";
	
	//// CONSTRUCTORS ////
	
	/**
	 * Konstruktor.
	 */
	public FileSource()
	{ 
		this.initialized = false;
		this.reader = null;
	}
	
	//// PUBLIC ////
	
	/* (non-Javadoc)
	 * @see cz.enif.commander.sources.ISource#init(String input)
	 */
	@Override
	public boolean init(String input) 
	{
		if (input == null || input.isEmpty())
		{
			return false;
		}
		
		if (this.initialized) this.close();
		
        try
        {
        	File file = new File(input);
        	if (file.isFile() == false)
        	{
        		Logger.error("FileSource: The '" + input + "' is not a file.");

    			return false;
        	}
        	
        	this.reader = new InputStreamReader(new FileInputStream(file), EXPECTED_FILE_ENCODING);
        }
        catch (FileNotFoundException e)
        {
            Logger.error("FileSource: File '" + input + "' not found.");

			return false;
        } catch (UnsupportedEncodingException e) {
        	Logger.error("FileSource: The " + EXPECTED_FILE_ENCODING + " encoding is not supported.");

			return false;
		}
        
        this.initialized = true;
        
        return true;
	}

	/* (non-Javadoc)
	 * @see cz.enif.commander.sources.ISource#next()
	 */
	@Override
	public int next() 
	{
		if (this.initialized == false || this.reader == null) return -1;
		
		int c = -1;
		try
		{
			c = this.reader.read();
		}
		catch (IOException e)
		{
			Logger.error("FileSource: IOException " + e.getMessage());

			this.close();
		}
		
		return c;
	}
	
	/* (non-Javadoc)
	 * @see cz.enif.commander.sources.ISource#close()
	 */
	@Override
	public void close()
	{
		if (this.initialized)
		{
			try
            {
                if (reader != null)
                {
                    reader.close();
                }
            }
            catch (IOException e)
            {
            	Logger.error("FileSource: IOException " + e.getMessage());
            }
			
			this.initialized = false;
			this.reader = null;
		}
	}
	
	//// PROTECTED ////
	
	protected void finalize() throws Throwable 
	{
	    try 
	    {
	        this.close(); 
	    } 
	    finally 
	    {
	        super.finalize();
	    }
	}
	
	////PRIVATE ////
   
    /** True, pokud již byl zdroj inicializován. */
	boolean initialized;
	
	/** Reader pro zdroj (čtený soubor). */
	private InputStreamReader reader;
}
